# -*- coding: utf-8 -*-
# @Author : zhaochen
# @Date   : 2019/1/30
# @File   : TX06_MonthlyTaxPayableAmtWithIndustry_GZ.py
# @E-mail : zhaochen@bbdservice.com

'''eof
name:月均所得税应纳税额一级行业
code:TX06_MonthlyTaxPayableAmtWithIndustry_GZ
tableName:
columnName:
groups:税务模块
dependencies:TX_GZ_DSJ
type:常用指标
datasourceType:在线指标
description:
eof'''

import sys
import re
import datetime
import pandas as pd
from collections import OrderedDict


reload(sys)
sys.setdefaultencoding('utf-8')

null_type_list = ['', ' ', None, 'null', 'Null', 'NULL', '/', '-', '--']

#两年数据
last_month_list = [(datetime.datetime.now() - pd.tseries.offsets.DateOffset(months=i)).strftime('%Y%m%d')[:6] \
                    for i in range(1, 25)]

def getTable(table_Name):
    '''
    获取表
    :param x:
    :return:
    '''
    try:
        ic_data = TX_GZ_DSJ['data'].get(table_Name)
        if ic_data in null_type_list:
            return [{}]
        else:
            return ic_data if isinstance(ic_data, list) and len(ic_data) > 0 else [{}]
    except:
        return [{}]

def isfloat(x):
    '''
    判断x为float类型
    :param x:
    :return:
    '''
    try:
        if isinstance(float(x), float):
            if str(x) in ['inf', 'infinity', 'INF', 'INFINITY', 'True', 'NAN', 'nan',
                     'False', '-inf', '-INF', '-INFINITY', '-infinity', 'NaN', 'Nan']:
                return False
            else:
                return True
        else:
            return False
    except:
        return False
# 行业
def Industry():
    syptGsdjxx = getTable('syptGsdjxx')
    if syptGsdjxx == [{}] or syptGsdjxx is None:
        return None
    else:
        HY_DM = syptGsdjxx[0].get('HY_DM')
        if isfloat(HY_DM) and HY_DM not in null_type_list:
            tmp = float(HY_DM[:2])
            if 51 <= tmp <= 52:
                return u'批发和零售业'
            elif 13 <= tmp <= 43:
                return u'制造业'
            else:
                return u'其他行业'
        else:
            return None

# 取税额
def getSEData(table, value):
    try:
        tax_list = OrderedDict()
        for k in last_month_list:
            tax_list.update({k: 'None'})
        flag = []
        for i in table:
            ND = i.get('ND')
            YF = i.get('YF')
            # 取纳税数据字段
            YNSEHJ = i.get(value)
            if isfloat(ND) and isfloat(YF) and isfloat(YNSEHJ) \
                    and ND not in null_type_list and YF not in null_type_list \
                    and YF in ['01', '02', '03', '04', '05', '06', '07',
                               '08', '09', '10', '11', '12']:
                key = str(ND) + str(YF)
                YNSEHJ = float(YNSEHJ)
                if tax_list.get(key) == 'None':
                    tax_list.update({key: YNSEHJ})
            else:
                flag.append(None)
                continue
        if len(flag) == len(table):
            tax_list = None
        return tax_list
    except:
        return None


def monthQuarterData2(tax_list):
    try:
        result = OrderedDict()
        # 为None
        if tax_list is None:
            for k in last_month_list:
                result.update({k: 0.0})
            return result
        # # 全为空
        # if len(set(tax_list.values())) == 1 and 'None' in tax_list.values():
        #     for k in tax_list:
        #         result.update({k: 0})
        #     return result
        # 填充若每月都有数据，则按月 直接返回
        # 若仅有季有数据，则按季进行拆分
        # 若中间有部分月缺失，则使用季的数据进行填充
        for k, v in tax_list.items():
            if k[4:] == '03':
                tmpMonth1 = k[:4] + '01'
                tmpMonth2 = k[:4] + '02'
                tmpMonth3 = k
                # 若全不为空 则按正常情况处理
                if tax_list.get(tmpMonth1) != 'None' and tax_list.get(tmpMonth2) != 'None' and tax_list.get(tmpMonth3) != 'None':
                    continue
                elif tax_list.get(tmpMonth3) != 'None':
                    tmp = v / 3.0
                    # 若季度不为空，但是前2个月为空，则用季度进行更新
                    if tax_list.get(tmpMonth2) == 'None' and tax_list.get(tmpMonth1) == 'None':
                        tax_list.update({tmpMonth3:tmp})
                        tax_list.update({tmpMonth2:tmp})
                        tax_list.update({tmpMonth1:tmp})
                    # 否则，优先使用月度数据，其次按季度进行更新
                    else:
                        if tax_list.get(tmpMonth1) == 'None':
                            tax_list.update({tmpMonth1: tmp})
                        if tax_list.get(tmpMonth2) == 'None':
                            tax_list.update({tmpMonth2: tmp})
                        tax_list.update({tmpMonth3: tmp})

            elif k[4:] == '06' and v != 'None':
                tmpMonth1 = k[:4] + '04'
                tmpMonth2 = k[:4] + '05'
                tmpMonth3 = k
                # 若全不为空 则按正常情况处理
                if tax_list.get(tmpMonth1) != 'None' and tax_list.get(tmpMonth2) != 'None' and tax_list.get(
                        tmpMonth3) != 'None':
                    continue
                elif tax_list.get(tmpMonth3) != 'None':
                    tmp = v / 3.0
                    # 若季度不为空，但是前2个月为空，则用季度进行更新
                    if tax_list.get(tmpMonth2) == 'None' and tax_list.get(tmpMonth1) == 'None':
                        tax_list.update({tmpMonth3: tmp})
                        tax_list.update({tmpMonth2: tmp})
                        tax_list.update({tmpMonth1: tmp})
                    # 否则，优先使用月度数据，其次按季度进行更新
                    else:
                        if tax_list.get(tmpMonth1) == 'None':
                            tax_list.update({tmpMonth1: tmp})
                        if tax_list.get(tmpMonth2) == 'None':
                            tax_list.update({tmpMonth2: tmp})
                        tax_list.update({tmpMonth3: tmp})
            elif k[4:] == '09' and v != 'None':
                tmpMonth1 = k[:4] + '07'
                tmpMonth2 = k[:4] + '08'
                tmpMonth3 = k
                # 若全不为空 则按正常情况处理
                if tax_list.get(tmpMonth1) != 'None' and tax_list.get(tmpMonth2) != 'None' and tax_list.get(
                        tmpMonth3) != 'None':
                    continue
                elif tax_list.get(tmpMonth3) != 'None':
                    tmp = v / 3.0
                    # 若季度不为空，但是前2个月为空，则用季度进行更新
                    if tax_list.get(tmpMonth2) == 'None' and tax_list.get(tmpMonth1) == 'None':
                        tax_list.update({tmpMonth3: tmp})
                        tax_list.update({tmpMonth2: tmp})
                        tax_list.update({tmpMonth1: tmp})
                    # 否则，优先使用月度数据，其次按季度进行更新
                    else:
                        if tax_list.get(tmpMonth1) == 'None':
                            tax_list.update({tmpMonth1: tmp})
                        if tax_list.get(tmpMonth2) == 'None':
                            tax_list.update({tmpMonth2: tmp})
                        tax_list.update({tmpMonth3: tmp})
            elif k[4:] == '12' and v != 'None':
                tmpMonth1 = k[:4] + '10'
                tmpMonth2 = k[:4] + '11'
                tmpMonth3 = k
                # 若全不为空 则按正常情况处理
                if tax_list.get(tmpMonth1) != 'None' and tax_list.get(tmpMonth2) != 'None' and tax_list.get(
                        tmpMonth3) != 'None':
                    continue
                elif tax_list.get(tmpMonth3) != 'None':
                    tmp = v / 3.0
                    # 若季度不为空，但是前2个月为空，则用季度进行更新
                    if tax_list.get(tmpMonth2) == 'None' and tax_list.get(tmpMonth1) == 'None':
                        tax_list.update({tmpMonth3: tmp})
                        tax_list.update({tmpMonth2: tmp})
                        tax_list.update({tmpMonth1: tmp})
                    # 否则，优先使用月度数据，其次按季度进行更新
                    else:
                        if tax_list.get(tmpMonth1) == 'None':
                            tax_list.update({tmpMonth1: tmp})
                        if tax_list.get(tmpMonth2) == 'None':
                            tax_list.update({tmpMonth2: tmp})
                        tax_list.update({tmpMonth3: tmp})
        return tax_list
    except:
        return None

#计算月均所得税应纳税额
def monthTaxPayableAmt():
    try:
        syptQysdsA1 = getTable('syptQysdsA1')
        syptQysdsNd = getTable('syptQysdsNd')
        # 初始化有序字典
        tax_list = OrderedDict()
        for k in last_month_list:
            tax_list.update({k:'None'})
        # 定义 近24个月包含的年份
        # year_list = [(datetime.datetime.now() - pd.tseries.offsets.DateOffset(months=1)).year-i for i in range(0,2)]
        # 分情况处理
        # 既有A1 又有 汇算清缴表
        if syptQysdsA1 != [{}] and syptQysdsNd != [{}]:
            #处理 汇算清缴表
            #对 汇算清缴表进行去重处理
            # syptQysdsNd = cleanSyptQysdsNd(syptQysdsNd)
            for Nd in syptQysdsNd:
                if isfloat(Nd.get('ND')) and Nd.get('ND') not in null_type_list \
                        and isfloat(Nd.get('YNSDSE')):
                    tmp = float(Nd.get('YNSDSE')) / 12.0
                    ND = Nd.get('ND')
                    # 若当前年度 纳税所得额为空 则跳过；同时，若多条则取第一条纳税额非空的记录存储
                    for k, v in tax_list.items():
                        if k[:4] == ND and v == 'None':
                            tax_list.update({k:tmp})
                        else:
                            pass
                else:
                    pass
            #取A1表数据 若tax_list_A1全为空则进行月均时，全部置为0 计算
            tax_list_A1 = getSEData(syptQysdsA1, 'YNSSDE')
            if tax_list_A1 != None:
                #对A1表的数据 进行 月均
                tax_list_A1 = monthQuarterData2(tax_list_A1)
                #对A1表的数据对 tax_list中为value=“None”的进行填充
                for k, v in tax_list.items():
                    if v == 'None':
                        # 更新 tax_list中的值
                        if tax_list_A1.get(k) != 'None':
                            tmp = tax_list_A1.get(k)
                            tax_list.update({k:tmp})
                        else:
                            #用0填充
                            tax_list.update({k:0.0})
                    else:
                        pass
            else:
                pass
            #返回有序键为‘年+月’，值为‘月均纳税额’的字典
            return tax_list
        #只有A1表
        elif syptQysdsA1 != [{}] and syptQysdsNd == [{}]:
            tax_list_A1 = getSEData(syptQysdsA1, 'YNSSDE')
            if tax_list_A1 != None:
                tax_list_A1 = monthQuarterData2(tax_list_A1)
                for k, v in tax_list_A1.items():
                    if v != 'None':
                        tax_list.update({k:v})
                    else:
                        tax_list.update({k:0.0})
                return tax_list
            else:
                return None
        #只有汇算清缴表
        elif syptQysdsA1 == [{}] and syptQysdsNd != [{}]:
            flag = []
            NDList = {}
            monthNow = datetime.datetime.now().month
            yearNow = datetime.datetime.now().year
            # 处理 汇算清缴表
            for Nd in syptQysdsNd:
                if isfloat(Nd.get('ND')) and Nd.get('ND') not in null_type_list \
                        and isfloat(Nd.get('YNSDSE')):
                    NDList.update({Nd.get('ND'): float(Nd.get('YNSDSE'))})
                else:
                    flag.append(None)
            if len(syptQysdsNd) == len(flag):
                return None
            else:
                result = []
                if monthNow > 5:
                    if NDList.get(str(yearNow - 1)) is not None:
                        result.append(NDList.get(str(yearNow - 1)))
                    if NDList.get(str(yearNow - 2)) is not None:
                        result.append(NDList.get(str(yearNow - 2)))
                    if result == []:
                        return None
                    else:
                        return round(sum(result) / (len(result) * 12.0), 4)
                else:
                    if NDList.get(str(yearNow - 1)) is not None:
                        result.append(NDList.get(str(yearNow - 1)))
                        if NDList.get(str(yearNow - 2)) is not None:
                            result.append(NDList.get(str(yearNow - 2)))
                    else:
                        if NDList.get(str(yearNow - 2)) is not None:
                            result.append(NDList.get(str(yearNow - 2)))
                        if NDList.get(str(yearNow - 3)) is not None:
                            result.append(NDList.get(str(yearNow - 3)))
                    if result == []:
                        return None
                    else:
                        return round(sum(result) / (len(result) * 12.0), 4)
        #两张表都没有
        elif syptQysdsA1 == [{}] and syptQysdsNd == [{}]:
            return None
    except:
        return None

def TX06_MonthlyTaxPayableAmtWithIndustry():
    try:
        Factor1 = Industry()
        Factor2 = monthTaxPayableAmt()
        if Factor1 is None or Factor2 is None:
            return u'缺失值'
        else:
            # 仅有年度汇算清缴表数据，则Factor2返回数值，否则Factor2为Dict
            if isinstance(Factor2, dict):
                tmp = [v for v in Factor2.values() if v != 'None' ]
                Factor2 = sum(tmp) / 24.0
            else:
                pass
            if Factor2 >= 0:
                if Factor1 == u'其他行业' and  0 <= Factor2 <= 4999.0673:
                    return 1
                elif Factor1 == u'制造业' and 0 <= Factor2 <= 1041.7317:
                    return 2
                elif Factor1 == u'批发和零售业' and  0 <= Factor2 <= 4999.0673:
                    return 3
                elif (Factor1 == u'制造业' and 1041.7317 < Factor2) \
                    or (Factor1 in [u'批发和零售业', u'其他行业'] and 4999.0673 < Factor2):
                    return 4
                else:
                    assert False
            else:
                return u'缺失值'
    except:
        return u'缺失值'

result = TX06_MonthlyTaxPayableAmtWithIndustry()